package com.example.demoapp;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.opengl.GLSurfaceView;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;

import com.softwinner.un.tool.video.GlViewDec;
import com.srtc.srtclibary.ISrtcService;
import com.srtc.srtclibary.IVideoListener;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "TestClient";
    private ISrtcService mService = null;
    private Button mStartStopButton = null;
    private RelativeLayout mRelativeLayout = null;

    private GlViewDec mRenderView; // GL View
    private Renderer mRenderer;
    private boolean isVideoViewShow = false;

    private static final int VIDEO_STATUS_STOP = 0;
    private static final int VIDEO_STATUS_STARTING = 1;
    private static final int VIDEO_STATUS_STARTED = 2;

    private int mVideoStatus = VIDEO_STATUS_STOP;
    private boolean mFocus = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG, "onCreate");
        setContentView(R.layout.activity_main);
        mStartStopButton = (Button) findViewById(R.id.startStopBtn);
        mStartStopButton.setOnClickListener(this);
        mStartStopButton.setText("start");
        mRelativeLayout = (RelativeLayout) findViewById(R.id.video_parentview);

        init();

        Intent intent = new Intent("com.srtc.srtclibary.SrtcService");
        intent.setPackage("com.example.demoapp");
        boolean ret = bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        Log.e(TAG, "---------------------------bindservice ret = " + ret);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.e(TAG, "onResume");
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        Log.e(TAG, "onWindowFocusChanged called hasFocus = " + hasFocus);
        mFocus = hasFocus;
        if(mFocus){
            startVideo();
        }else{
            stopVideo();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG, "onPause");
        if (VIDEO_STATUS_STARTED == mVideoStatus && null != mService) {
            try {
                mService.removeVideoListener();
                int ret = mService.stopVideo();
                if (ret == 1) {
                    mVideoStatus = VIDEO_STATUS_STOP;
                    Log.e(TAG, "start video success!!!");
                    mStartStopButton.setText("start");
                }
                mRenderer.setInitPending(true);
            } catch (RemoteException e) {

            }
        }

    }

    @Override
    protected void onDestroy() {
        Log.e(TAG, "onDestroy");
        unbindService(mServiceConnection);
        super.onDestroy();
    }

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = ISrtcService.Stub.asInterface(service);
            Log.e(TAG, "+++++++++++++++++++service connected");
            startVideo();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mService = null;
            Log.e(TAG, "service disconnected");
        }
    };

    private void init() {
        // create renderView
        mRenderView = new GlViewDec(this);
        mRelativeLayout.addView(mRenderView); // 把此view添加到容器中

        // init renderView layout
        ViewGroup.LayoutParams params = mRenderView.getLayoutParams();
        params.height = ViewGroup.LayoutParams.MATCH_PARENT;
        params.width = ViewGroup.LayoutParams.MATCH_PARENT;
        mRenderView.setLayoutParams(params);
        mRenderView.setZOrderOnTop(false);

        // init callback
        mRenderView.getHolder().addCallback(new SurfaceHolder.Callback() {
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                Log.e(TAG, " Video display surface is being changed. "
                        + "width " + width + "; height " + height);
            }

            public void surfaceCreated(SurfaceHolder holder) {
                Log.e(TAG, "Video display surface created");
            }

            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.e(TAG, "Video display surface destroyed");
            }
        });
        mRenderer = new Renderer();
        mRenderView.setRenderer(mRenderer);
        // ((GLSurfaceView)
        // mRenderView).setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);//render
        // by jni call back
        mRenderView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }

    /**
     * setOpenGLESDisplay
     *
     * @param ptr
     */
    private void setOpenGLESDisplay(int ptr) {
        Log.e(TAG, "setOpenGLESDisplay");
        mRenderer.setOpenGLESDisplay(ptr);
    }

    /**
     * iFrame return， callback here
     */
    private void showFrameCallBack() {
        if (!isVideoViewShow) {
            onVideoViewShow();
            isVideoViewShow = true;
        } else {
            onVideoViewShowing();
        }
    }

    /**
     * when uninit frame ,callback here
     */
    private void stopFrameCallBack() {
        Log.e(TAG, "stopFrameCallBack");
        isVideoViewShow = false;
        onVideoViewEnd();
    }

    private class Renderer implements GLSurfaceView.Renderer {
        int ptr;
        boolean initPending;
        int width, height;

        public Renderer() {
            Log.e(TAG, "Renderer Create");
            ptr = 0;
            initPending = false;
        }

        public void setInitPending(boolean pending) {
            initPending = pending;
        }

        public void setOpenGLESDisplay(int ptr) {
            Log.e(TAG, "*****************setOpenGLESDisplay ptr = " + ptr);
            synchronized (this) {
                if (this.ptr != 0 && ptr != this.ptr) {
                    initPending = true;
                }
                this.ptr = ptr;
            }
        }

        /**
         * 刷新视频界面（现在是自动模式）
         */

        public void onDrawFrame(GL10 gl) {

            //Log.e(TAG, "*****************onDrawFrame");
            synchronized (this) {
                if (ptr == 0) {
                    //Log.e(TAG, "onDrawFrame clear");
                    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 设置清除颜色设为黑
                    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
                    if (null != mService) {
                        try {
                            ptr = mService.getPtr();
                            Log.e(TAG, "onDrawFrame getPtr ptr = " + ptr);
                            if (0 == ptr) {
                                return;
                            }
                        } catch (Exception e) {
                            return;
                        }
                    }
//                    return;
                }

                if (initPending) {
                    boolean error = false;
                    try {
                        if (null != mService) {
                            int ret = mService.init(ptr, width, height);
                            Log.e(TAG, "onDrawFrame init ret = " + ret + " ptr = " + ptr + " width = " + width + " height = " + height);
                        }
                    } catch (Exception e) {
                        error = true;
                    }
                    if (!error) {
                        initPending = false;
                    }
                }

                try {
                    if (null != mService) {
                        mService.render(ptr);// 更新画面
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                }

            }
        }

        public void onSurfaceChanged(GL10 gl, int width, int height) {
            Log.e(TAG, "onSurfaceChanged width " + width + "; height " + height);
            this.width = width;
            this.height = height;
            initPending = true;
        }

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            Log.e(TAG, "onSurfaceCreated");
        }
    }

    private void stopVideo() {
        try {
            if (VIDEO_STATUS_STARTED == mVideoStatus && null != mService) {
                mService.removeVideoListener();
                int ret = mService.stopVideo();
                if (ret == 1) {
                    mVideoStatus = VIDEO_STATUS_STOP;
                    Log.e(TAG, "start video success!!!");
                    mStartStopButton.setText("start");
                }
                mRenderer.setInitPending(true);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private void startVideo() {
        try {
            if (VIDEO_STATUS_STOP == mVideoStatus && null != mService && mFocus) {
                mService.setVideoListener(mVideoListener);
                if (1 == mService.getConnectStatus()) {
                    int ret = mService.startVideo();
                    if (ret == 1) {
                        mVideoStatus = VIDEO_STATUS_STARTING;
                        Log.e(TAG, "start video success!!!");
                        mStartStopButton.setText("starting");
                    }
                    mRenderer.setInitPending(true);
                }
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.startStopBtn:
                if (VIDEO_STATUS_STOP == mVideoStatus) {
                    startVideo();
                } else if (VIDEO_STATUS_STARTED == mVideoStatus && null != mService) {
                    stopVideo();
                }
                break;
        }
    }

    private void onVideoViewEnd() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mStartStopButton.setText("start");
                mVideoStatus = VIDEO_STATUS_STOP;
            }
        });
    }

    private void onVideoViewShowing() {
    }

    private void onVideoViewShow() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mStartStopButton.setText("stop");
                mVideoStatus = VIDEO_STATUS_STARTED;
            }
        });

    }

    private IVideoListener.Stub mVideoListener = new IVideoListener.Stub() {

        @Override
        public void onStopFrameCallback() throws RemoteException {
            Log.e(TAG, "+++++++++++++++++++onStopFrameCallback");
            stopFrameCallBack();
        }

        @Override
        public void onSetOpenGLESDisplay(int ptr) throws RemoteException {
            Log.e(TAG, "+++++++++++++++++++onSetOpenGLESDisplay ptr = " + ptr);
            setOpenGLESDisplay(ptr);
        }

        @Override
        public void onShowFrameCallBack() throws RemoteException {
            //Log.e(TAG, "+++++++++++++++++++onShowFrameCallBack");
            showFrameCallBack();
        }

        @Override
        public void onConnectStatusChange(int connected) throws RemoteException {
            Log.e(TAG, "+++++++++++++++++++onConnectStatusChange connected = " + connected);
            if(1 == connected) {
                startVideo();
            }
        }


    };


}
